home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 June / EnigmA AMIGA RUN 08 (1996)(G.R. Edizioni)(IT)[!][issue 1996-06][EARSAN CD VII].iso / earcd / c-lang / vbcc.lha / vbcc / preproc.c < prev    next >
C/C++ Source or Header  |  1996-05-05  |  55KB  |  2,504 lines

  1. /* TODO:
  2.  
  3.    ---- HIGHEST PRIORITY ----
  4.  
  5.    * #ifndef
  6.  
  7.    * #if/#elif - Bearbeitung
  8.  
  9.    * leere argument-/tokenlists erlauben
  10.  
  11.    * Anzahl der Argumente checken (auch zuviele ergeben einen Error)
  12.  
  13.    * bei REDEFINING und allowredefinition=0 tokenlist genau ueberpruefen
  14.  
  15.    * Aufteilen in mehrere Sourcen main.c pplists.c etc.
  16.    * Einige Variablen umbenennen (x,y,i,j,l,n etc =8)
  17.  
  18.    -----------------------------------------------------------------
  19.  
  20.    * Verbesserungen:
  21.    * - Nach malloc()/vor free() ueberpruefen ob NULL-Pointer
  22.    * - Statt per dlen per Ptr2EOL abfragen..
  23.  
  24.    * Fragen an Volker:
  25.    * - _ alleine ein Identifier ? Ja
  26.  
  27.    ---- LOWEST PRIORITY ----
  28.  
  29.    * - Token loeschen, wenn nur noch TokenList benutzt wird.
  30.  
  31.    * - ParseIdent.. optimieren
  32.  
  33.    * - Rest optimieren =8)
  34.  
  35.    * - PreParsing umschreiben.. __LINE__ muss mit der echten
  36.    *    Zeilennummer uebereinstimmen (die LFs drinlassen)
  37.  */
  38.  
  39. /*
  40.  * PreProcessor
  41.  * $VER: VBPP V0.00 (19 Sep 1995)
  42.  * (w) 1995 by Thorsten Schaaps
  43.  */
  44.  
  45. #include <time.h>
  46.  
  47. #include "vbc.h"
  48. #include "vbpp.h"
  49.  
  50. /*vb:   */
  51. char pp_version[] = "vbpp V0.00 (w) 1995 by Thorsten Schaaps";
  52.  
  53.                 /* #define MAXIFNESTING 1024 *//*vb: ifnesting==incnesting */
  54.  
  55. FILE *in[MAXINCNESTING];    /*  Sourcefiles     */
  56. int zn[MAXINCNESTING];        /*  Zeilennummern   */
  57. char *filename[MAXINCNESTING];    /*  Filenamen   */
  58. int incnesting;            /*  aktuelle Verschachtelungstiefe  */
  59. unsigned long linenr;        /*  Zeilennummer */
  60.  
  61. char *incpath[MAXINCPATHS] =
  62. {"vinclude:"};            /*  Includepfade    */
  63.  
  64. int incpathc = 1;        /*  Anzahl der Includepfade     */
  65.  
  66. char ppstring[MAXPPINPUT];
  67.  
  68. int cmtnesting = 0;        /*  aktuelle Kommentar-Versch.-Tiefe */
  69.  
  70.                       /*int ifnesting; *//*vb: *//*  aktuelle IF-Tiefe */
  71. /*vb: ifnesting==incnesting */
  72. short ifstatus[MAXINCNESTING];    /* Array fuer Status-Verschachtelung */
  73. int if_cnt;            /* Zaehler fuer #if's waehrend do_output=0 */
  74. int abs_if_cnt;            /* zaehlt auch waehrend do_output */
  75.  
  76. int do_output = 1;        /* Flag zur Erzeugung eines Outputs */
  77.  
  78. struct strnode *strlist;
  79.  
  80. struct mnode *mlist;
  81.  
  82. int did_expand;
  83.  
  84. /* Temporaere Debugging-Routinen */
  85. void PrintSN(struct strnode *tl)
  86. {
  87.     switch (tl->type) {
  88.     case NORMAL:
  89.     printf(" Normal........:");
  90.     break;
  91.     case PP_IDENT:
  92.     printf(" Identifier....:");
  93.     break;
  94.     case ARGUMENT:
  95.     printf(" Argument Nr.%2d:", tl->number);
  96.     break;
  97.     case NUMBER:
  98.     printf(" Number........:");
  99.     break;
  100.     case PP_STR:
  101.     printf(" String........:");
  102.     break;
  103.     case SPACE:
  104.     printf(" Space.........:");
  105.     break;
  106.     case SPECIAL:
  107.     printf(" Special..Nr.%2d:", tl->flags);
  108.     break;
  109.     default:
  110.     printf(" unknown..Nr.%2d:", tl->type);
  111.     break;
  112.     }
  113.     printf(" %s\n", tl->str);
  114. }
  115. void PrintTL(struct strnode *tl)
  116. {
  117.  
  118. #ifdef bla
  119.  
  120.     if (tl) {
  121.     printf("TokenList:\n");
  122.     while (tl) {
  123.         PrintSN(tl);
  124.         tl = tl->next;
  125.     }
  126.     }
  127. #endif
  128.  
  129. }
  130.  
  131.  
  132. /* ******* Listen-Funktionen ******* */
  133.  
  134. /* AddMakroNode - Fuegt eine Node an den Anfang einer Liste ein */
  135. void AddMakroNode(struct mnode **list, struct mnode *node)
  136. {
  137.  
  138.     if (DEBUG & 32)
  139.     puts("AddMakroNode");
  140.  
  141.     if (node) {
  142.     node->prev = NULL;
  143.     node->next = *list;
  144.     *list = node;
  145.     if (node->next)
  146.         node->next->prev = node;
  147.     }
  148. }
  149.  
  150.  
  151. /* AddStrNode - Fuegt eine Node in die Liste ein */
  152. void AddStrNode(struct strnode **list, struct strnode *node, char *str)
  153. {
  154.  
  155.     if (DEBUG & 32)
  156.     puts("AddStrNode");
  157.  
  158.  
  159.     if (node || str) {
  160.     if (!node)
  161.         node = (struct strnode *) malloc(sizeof(struct strnode));
  162.     /* HIER: Rueckgabewert wegen Fehler ! */
  163.     if (!node) {
  164.         error(196);
  165.     } else {
  166.         node->prev = NULL;
  167.         node->next = *list;
  168.         if (str)
  169.         node->str = str;
  170.         *list = node;
  171.         if (node->next)
  172.         node->next->prev = node;
  173.     }
  174.     }
  175. }
  176.  
  177.  
  178. /* AddStrNodeBehind - Fuegt eine Node ans Ende der Liste ein */
  179. void AddStrNodeBehind(struct strnode **list, struct strnode *node, char *str)
  180. {
  181.     struct strnode *listnode;
  182.  
  183.     if (DEBUG & 32)
  184.     puts("AddStrNodeBehind");
  185.  
  186.  
  187.     if (node || str) {
  188.     if (!node)
  189.         node = (struct strnode *) malloc(sizeof(struct strnode));
  190.     if (!node) {
  191.         error(196);
  192.     } else {
  193.         if (!*list) {
  194.         node->prev = NULL;
  195.         node->next = NULL;
  196.         *list = node;
  197.         } else {
  198.         listnode = *list;
  199.         while (listnode->next) {
  200.             listnode = listnode->next;
  201.         }
  202.         node->prev = listnode;
  203.         node->next = NULL;
  204.         listnode->next = node;
  205.         }
  206.         if (str)
  207.         node->str = str;
  208.     }
  209.     }
  210. }
  211.  
  212.  
  213. /* RemMakroNode - Entfernt eine Node aus der Liste ohne sie zu loeschen */
  214. void RemMakroNode(struct mnode **list, struct mnode *node)
  215. {
  216.  
  217.     if (DEBUG & 32)
  218.     puts("RemMakroNode");
  219.  
  220.  
  221.     if (node->prev) {
  222.     if (node->next)
  223.         node->next->prev = node->prev;
  224.     node->prev->next = node->next;
  225.     } else {
  226.     if (node->next)
  227.         node->next->prev = NULL;
  228.     *list = node->next;
  229.     }
  230.     node->next = node->prev = NULL;
  231. }
  232.  
  233. /* InsertMakroNode - Setzt eine Node hinter einer anderen ein */
  234. void InsertMakroNode(struct mnode **list, struct mnode *node, struct mnode *behind)
  235. {
  236.  
  237.     if (DEBUG & 32)
  238.     puts("InsertMakroNode");
  239.  
  240.  
  241.     if (behind) {
  242.     node->prev = behind;
  243.     node->next = behind->next;
  244.     behind->next = node;
  245.     if (node->next)
  246.         node->next->prev = node;
  247.     } else
  248.     AddMakroNode(list, node);
  249. }
  250.  
  251. /* RemStrNode - Entfernt eine Node aus der Liste ohne sie zu loeschen */
  252. void RemStrNode(struct strnode **list, struct strnode *node)
  253. {
  254.  
  255.     if (DEBUG & 32)
  256.     puts("RemStrNode");
  257.  
  258.  
  259.     if (node->prev) {
  260.     if (node->next)
  261.         node->next->prev = node->prev;
  262.     node->prev->next = node->next;
  263.     } else {
  264.     if (node->next)
  265.         node->next->prev = NULL;
  266.     *list = node->next;
  267.     }
  268.     node->next = node->prev = NULL;
  269. }
  270.  
  271.  
  272. /* FindMakroNode - sucht den passenden Eintrag in der Liste
  273.  *                 len=0 - der gesamte String muss uebereinstimmen
  274.  *                 len>0 - die ersten len Zeichen muessen stimmen
  275.  */
  276. struct mnode *FindMakroNode(struct mnode *list, char *str, int len)
  277. {
  278.  
  279.     if (DEBUG & 32)
  280.     puts("FindMakroNode");
  281.  
  282.     while (list) {
  283.     if (len) {
  284.         if ((strlen(list->name) == len) && (!strncmp(list->name, str, len)))
  285.         return (list);
  286.     } else {
  287.         if (!strcmp(list->name, str))
  288.         return (list);
  289.     }
  290.     list = list->next;
  291.     }
  292.     return (0);
  293. }
  294.  
  295.  
  296. /* DelMakroNode - gibt den gesamten Speicher einer Node frei, ist list#NULL
  297.  *                wird die Node vorher aus der Liste entfernt
  298.  */
  299. void DelMakroNode(struct mnode **list, struct mnode *node)
  300. {
  301.  
  302.     if (DEBUG & 32)
  303.     puts("DelMakroNode");
  304.  
  305.  
  306.     if (node) {
  307.     if (list && *list)
  308.         RemMakroNode(list, node);
  309.     if (node->name)
  310.         free(node->name);
  311.     if (node->args)
  312.         free(node->args);
  313.     if (node->token)
  314.         free(node->token);
  315.     if (node->tokenlist)
  316.         DelStrList(&node->tokenlist);
  317.     free(node);
  318.     }
  319. }
  320.  
  321.  
  322. /* DelStrNode - gibt den gesamten Speicher einer Node frei, ist list#NULL
  323.  *              wird die Node vorher aus der Liste entfernt
  324.  */
  325. void DelStrNode(struct strnode **list, struct strnode *node)
  326. {
  327.  
  328.     if (DEBUG & 32)
  329.     puts("DelStrNode");
  330.  
  331.  
  332.     if (node) {
  333.     if (list && *list)
  334.         RemStrNode(list, node);
  335.     if (node->str)
  336.         free(node->str);
  337.     free(node);
  338.     }
  339. }
  340.  
  341. void MergeStrNodes(struct strnode *prev, struct strnode *next)
  342. {
  343.     /* next will now be deleted and prev->str will be */
  344.     /* the joined strings from prev&next */
  345.     char *newstr;
  346. /*vb:   */
  347.     char c, *s, *d;
  348.  
  349.     if (DEBUG & 32)
  350.     puts("MergeStrNodes");
  351.  
  352.  
  353.     newstr = (char *) malloc(prev->len + next->len + 1);
  354. /*vb: string-Routinen ersetzt (hoffentlich schneller)
  355.    strcpy(newstr,prev->str);
  356.    strcat(newstr,next->str);
  357.  */
  358.     d = newstr;
  359.     s = prev->str;
  360.     do {
  361.     c = *s++;
  362.     *d++ = c;
  363.     } while (c);
  364.     d--;
  365.     s = next->str;
  366.     do {
  367.     c = *s++;
  368.     *d++ = c;
  369.     } while (c);
  370.  
  371.     if (prev->str)
  372.     free(prev->str);    /*vb: wenn prev->str==0 knallts doch schon oben? */
  373.     prev->str = newstr;
  374.     prev->len += next->len;
  375.     DelStrNode(NULL, next);
  376. }
  377.  
  378. /* DelMakroList - loescht eine gesamte Liste */
  379. void DelMakroList(struct mnode **list)
  380. {
  381.  
  382.     if (DEBUG & 32)
  383.     puts("DelMakroList");
  384.  
  385.  
  386.     while (*list)
  387.     DelMakroNode(list, *list);
  388.     /*  *list=NULL; *//*vb: *list==0 */
  389. }
  390.  
  391.  
  392. /* DelStrList - loescht eine gesamte Liste samt der Nodes/Strings */
  393. void DelStrList(struct strnode **list)
  394. {
  395.  
  396.     if (DEBUG & 32)
  397.     puts("DelStrList");
  398.  
  399.  
  400.     while (*list)
  401.     DelStrNode(list, *list);
  402.     /*  *list=NULL; *//*vb: *list==0 */
  403. }
  404.  
  405. /* AllocSpace - erzeugt eine StrNode vom Typ Space */
  406. struct strnode *AllocSpace()
  407. {
  408.     struct strnode *newnode;
  409.     char *newstr;
  410.  
  411.  
  412.     if (DEBUG & 32)
  413.     puts("AllocSpace");
  414.  
  415.  
  416.     newstr = (char *) malloc(2);
  417.     if (newstr) {
  418.     newstr[0] = ' ';
  419.     newstr[1] = 0;
  420.     newnode = (struct strnode *) malloc(sizeof(struct strnode));
  421.     if (newnode) {
  422.         newnode->str = newstr;
  423.         newnode->type = SPACE;
  424.         newnode->len = 1;
  425.         newnode->next = newnode->prev = NULL;
  426.         newnode->flags = newnode->number = 0;
  427.         return (newnode);
  428.     }
  429.     }
  430.     return (NULL);
  431. }
  432.  
  433.  
  434. /* CloneStrList - erstellt eine exakte Kopie der Liste oder eines Ausschnittes */
  435. /*                wenn listend#NULL */
  436. struct strnode *CloneStrList(struct strnode *list, struct strnode *listend)
  437. {
  438.     struct strnode *prevnode = NULL, *newnode, *newlist = NULL;
  439.     char *newstr;
  440.  
  441.     if (DEBUG & 32)
  442.     puts("CloneStrList");
  443.  
  444.  
  445.     while (list) {
  446.     newnode = (struct strnode *) malloc(sizeof(struct strnode));
  447.     if (!newnode) {
  448.         DelStrList(&newlist);
  449.         return (NULL);
  450.     }
  451.     newstr = (char *) malloc(list->len + 1);
  452.     if (!newstr) {
  453.         free(newnode);
  454.         DelStrList(&newlist);
  455.         return (NULL);
  456.     }
  457.     strcpy(newstr, list->str);
  458.     newnode->str = newstr;
  459.     newnode->len = list->len;
  460.     newnode->flags = list->flags;
  461.     newnode->type = list->type;
  462.     newnode->number = list->number;
  463.     newnode->next = NULL;
  464.     newnode->prev = prevnode;
  465.  
  466.     if (prevnode)
  467.         prevnode->next = newnode;
  468.     else
  469.         newlist = newnode;
  470.     prevnode = newnode;
  471.  
  472.     if (listend && list == listend)
  473.         list = NULL;
  474.     else
  475.         list = list->next;
  476.     }
  477.     return (newlist);
  478. }
  479.  
  480.  
  481. /* DoMakroFunction - erstellt eine StrList entsprechend des Function-Makros */
  482. struct strnode *DoMakroFunction(struct mnode *makro)
  483. {
  484.     struct strnode *result = NULL;
  485.     char *newstr = NULL, *timestr = NULL;
  486.     int len, type;
  487.     time_t timevalue;
  488.  
  489.     if (DEBUG & 32)
  490.     puts("DoMakroFunction");
  491.  
  492.  
  493.     if (makro->flags & FUNCTION) {
  494.     switch (makro->funcnum) {
  495.     case FUNCLINE:
  496.         newstr = (char *) malloc(11);
  497.         if (!newstr)
  498.         return (NULL);
  499.         sprintf(newstr, "%lu", linenr);
  500.         len = strlen(newstr);
  501.         type = NUMBER;
  502.         break;
  503.     case FUNCFILE:
  504.         len = strlen(filename[incnesting]);
  505.         newstr = (char *) malloc(len + 1 + 2);
  506.         if (!newstr)
  507.         return (NULL);
  508.         *newstr = '\"';
  509.         strcpy((newstr + 1), filename[incnesting]);
  510.         strcat(newstr, "\"");
  511.         type = PP_STR;
  512.         break;
  513.     case FUNCDATE:
  514.         type = PP_STR;
  515.         newstr = (char *) malloc(14);
  516.         if (!newstr)
  517.         return (NULL);
  518.         timevalue = time(0);
  519.         timestr = ctime(&timevalue);
  520.         newstr[0] = '\"';
  521.         strncpy(newstr + 1, timestr + 4, 7);    /* copy 'Mmm dd ' */
  522.         strcpy(newstr + 8, timestr + 20);    /* copy 'yyyy' */
  523.         newstr[12] = '\"';
  524.         newstr[13] = 0;
  525.         len = 13;
  526.         break;
  527.     case FUNCTIME:
  528.         type = PP_STR;
  529.         newstr = (char *) malloc(11);
  530.         if (!newstr)
  531.         return (NULL);
  532.         timevalue = time(0);
  533.         timestr = ctime(&timevalue);
  534.         newstr[0] = '\"';
  535.         strncpy(newstr + 1, timestr + 11, 8);    /* copy 'hh:mm:ss' */
  536.         newstr[9] = '\"';
  537.         newstr[10] = 0;
  538.         len = 10;
  539.         break;
  540.     default:
  541.         return (NULL);
  542.         break;
  543.     }
  544.     result = (struct strnode *) malloc(sizeof(struct strnode));
  545.     if (!result) {
  546.         if (newstr)
  547.         free(newstr);
  548.         return (NULL);
  549.     }
  550.     result->prev = result->next = NULL;
  551.     result->str = newstr;
  552.     result->len = len;
  553.     result->number = result->flags = 0;
  554.     result->type = type;
  555.     }
  556.     return (result);
  557. }
  558.  
  559.  
  560. /* *******  String-Funktionen ****** */
  561.  
  562. /* Str2List - parsed einen String in eine StrList */
  563. struct strnode *Str2List(char *str)
  564. {
  565.     struct strnode *newlist = NULL, *newnode = NULL;
  566.     char *temp, *string;
  567.     int length, type, flags;
  568.  
  569.     if (DEBUG & 32)
  570.     puts("Str2List");
  571.  
  572.     while (*str) {
  573.     flags = 0;
  574. /*vb: casts eingefuegt   */
  575.     if (isspace((unsigned char) *str)) {    /* Spaces parsen */
  576.         temp = str + 1;
  577.         length = 1;
  578.         while (*temp && isspace((unsigned char) *temp)) {
  579.         temp++;
  580.         length++;
  581.         }
  582.         type = SPACE;
  583.     } else if (*str == '\"') {    /* String parsen */
  584.         temp = str + 1;
  585.         length = 2;
  586.         while (*temp && *temp != '\"')
  587.         if (*temp == '\\') {
  588.             temp += 2;
  589.             length += 2;
  590.         } else {
  591.             temp++;
  592.             length++;
  593.         }
  594.         type = PP_STR;
  595.     } else if (*str == '\'') {    /* String parsen */
  596.         temp = str + 1;
  597.         length = 2;
  598.         while (*temp && *temp != '\'')
  599.         if (*temp == '\\') {
  600.             temp += 2;
  601.             length += 2;
  602.         } else {
  603.             temp++;
  604.             length++;
  605.         }
  606.         type = PP_STR;
  607.     } else if (isdigit((unsigned char) *str) || (*str == '.' && isdigit((unsigned char) *(str + 1)))) {
  608.         /* Zahlen parsen */
  609.         temp = str;
  610.         length = 0;
  611.         while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
  612.         temp++;
  613.         length++;
  614.         }
  615.         if (*temp == '.') {
  616.         temp++;
  617.         length++;
  618.         if (isdigit((unsigned char) *temp) || *temp == 'e' || *temp == 'E')
  619.             while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
  620.             temp++;
  621.             length++;
  622.             }
  623.         }
  624.         if (*(temp - 1) == 'e' || *(temp - 1) == 'E')
  625.         if (isdigit((unsigned char) *temp) || *temp == '+' || *temp == '-') {
  626.             temp++;
  627.             length++;
  628.             while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
  629.             temp++;
  630.             length++;
  631.             }
  632.         }
  633.         type = NUMBER;
  634.     } else if (isalpha((unsigned char) *str) || *str == '_') {    /* moegl. Identifier parsen */
  635.         temp = str + 1;
  636.         length = 1;
  637.         while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
  638.         temp++;
  639.         length++;
  640.         }
  641.         type = PP_IDENT;
  642.     } else if (*str) {    /* alles andere als einzelne Zeichen */
  643.         length = 1;
  644.         type = NORMAL;
  645.     }
  646.     string = (char *) malloc(length + 1);
  647.     if (!string) {
  648.         error(196);
  649.         DelStrList(&newlist);
  650.         return (NULL);
  651.     }
  652.     strncpy(string, str, length);
  653.     string[length] = 0;
  654.     str += length;
  655.  
  656.     newnode = (struct strnode *) malloc(sizeof(struct strnode));
  657.     if (!newnode) {
  658.         error(196);
  659.         if (string)
  660.         free(string);
  661.         return (NULL);
  662.     }
  663.     newnode->str = string;
  664.     newnode->len = length;
  665.     newnode->flags = flags;
  666.     newnode->type = type;
  667.  
  668.     AddStrNodeBehind(&newlist, newnode, NULL);
  669.     }
  670.     return (newlist);
  671. }
  672.  
  673. /* List2Str - schreibt eine Liste als String zurueck */
  674. int List2Str(struct strnode *list, char *str, int maxchars)
  675. {
  676.     int len = 0;
  677.     char c, *p;
  678.  
  679.     if (DEBUG & 32)
  680.     puts("List2Str");
  681.  
  682.  
  683.     *str = 0;
  684.     if (list) {
  685.     while (list) {
  686.         if ((len + (list->len)) > (maxchars - 1)) {
  687.         error(177);
  688.         return (0);
  689.         } else {
  690.         /*vb:   */
  691.         p = list->str;
  692.         do {
  693.             c = *p++;
  694.             *str++ = c;
  695.         } while (c);
  696.         str--;
  697. /*        strcat(str,list->str); */
  698.         len += list->len;
  699.         }
  700.         list = list->next;
  701.     }
  702.     return (len + 1);
  703.     } else {
  704.     *str = 0;
  705.     return (1);
  706.     }
  707. }
  708.  
  709. /* ListLen - ermittelt die Laenge einer Str-Liste (in Zeichen) */
  710. int ListLen(struct strnode *list)
  711. {
  712.     int len = 0;
  713.     while (list) {
  714.     len += list->len;
  715.     list = list->next;
  716.     }
  717.     return (len);
  718. }
  719.  
  720. /* ListStrLen - ermittelt die Laenge einer Str-List als String   */
  721. /*              d.h. mit " am Anfang und Ende, sowie einem \ vor */
  722. /*              jedem \ und "                                    */
  723. int ListStrLen(struct strnode *list)
  724. {
  725.     int len = 2;
  726.     while (list) {
  727.     if (list->type == SPACE)
  728.         len++;
  729.     else {
  730.         len += list->len;
  731.         if (list->type == PP_STR && list->str[0] == '\"')
  732.         len += 2;
  733.         else if (list->type == NORMAL && list->str[0] == '\\')
  734.         len++;
  735.     }
  736.     list = list->next;
  737.     }
  738.     return (len);
  739. }
  740.  
  741. /* CopyList2StrStr - kopiert eine Str-List als String um         */
  742. /*              d.h. mit " am Anfang und Ende, sowie einem \ vor */
  743. /*              jedem \ und "                                    */
  744. CopyList2StrStr(struct strnode * list, char *str)
  745. {
  746.     int len;
  747.  
  748.     if (DEBUG & 32)
  749.     puts("CopyList2StrStr");
  750.  
  751.  
  752.     str[0] = 0;
  753.     if (list) {
  754.     strcpy(str, "\"");
  755.     len = 1;
  756.     while (list) {
  757.         if (list->type == SPACE) {
  758.         len++;
  759.         strcat(str, " ");
  760.         } else {
  761.         len += list->len;
  762.         if (list->type == PP_STR && list->str[0] == '\"') {
  763.             strcat(str, "\\");
  764.             strncat(str, list->str, list->len - 1);
  765.             strcat(str, "\\\"");
  766.         } else if (list->type == NORMAL && list->str[0] == '\\') {
  767.             strcat(str, "\\");
  768.             strcat(str, list->str);
  769.         } else
  770.             strcat(str, list->str);
  771.         }
  772.         list = list->next;
  773.     }
  774.     strcat(str, "\"");
  775.     len++;
  776.     }
  777.     return (len);
  778. }
  779.  
  780. /* NextToSpecial - checked, ob die StrNode neben einem # oder ## steht */
  781. int NextToSpecial(struct strnode *node)
  782. {
  783.     struct strnode *search;
  784.  
  785.     if (DEBUG & 32)
  786.     puts("NextToSpecial");
  787.  
  788.  
  789.     if (node->prev) {
  790.     search = node->prev;
  791.     while (search && search->type == SPACE)
  792.         search = search->prev;
  793.     if (search && search->type == SPECIAL)
  794.         return (search->flags);
  795.     }
  796.     if (node->next) {
  797.     search = node->next;
  798.     while (search && search->type == SPACE)
  799.         search = search->next;
  800.     /* Hinter der Node ist ein # (ToString) ohne Bedeutung */
  801.     if (search && search->type == SPECIAL
  802.         && search->flags == KILLSPACES)
  803.         return (KILLSPACES);
  804.     }
  805.     return (NONE);
  806. }
  807.  
  808. /* FindBracket - sucht das passende Gegenstueck zu der (, auf die Node zeigt */
  809. /*               dabei werden verschachtelte Klammern beachtet               */
  810. struct strnode *FindBracket(struct strnode *node)
  811. {
  812.  
  813.     if (DEBUG & 32)
  814.     puts("FindBracket");
  815.  
  816.  
  817.     if (node && node->next && node->type == NORMAL && node->str[0] == '(') {
  818.     do {
  819.         node = node->next;
  820.         if (node && node->type == NORMAL) {
  821.         if (node->str[0] == ')')
  822.             return (node);
  823.         if (node->str[0] == '(')
  824.             node = FindBracket(node);
  825.         }
  826.     } while (node);
  827.     return (NULL);
  828.     } else
  829.     return (NULL);
  830. }
  831.  
  832. /* CloneArg - gibt eine Liste zurueck, die das n. Argument des Makros enthaelt */
  833. struct strnode *CloneArg(struct strnode *list, int n, int *error)
  834. {
  835.     int argnum = 0;
  836.     struct strnode *start;
  837.  
  838.     if (error)
  839.     *error = OK;
  840.  
  841.     if (list) {
  842.     if (DEBUG & 32)
  843.         printf("CloneArg\n");
  844.     if (list->type == PP_IDENT)
  845.         list = list->next;
  846.     while (list && list->type == SPACE)
  847.         list = list->next;
  848.  
  849.     if (list && list->type == NORMAL && list->str[0] == '(') {
  850.         list = list->next;    /* Skip ( */
  851.  
  852.         if (DEBUG & 32)
  853.         printf("- IDENT skipped, ( found\n");
  854.  
  855.         while (list && (argnum < n)) {
  856.         if (list->type == NORMAL) {
  857.             if (list->str[0] == ')')
  858.             list = NULL;
  859.             if (list && list->str[0] == '(')
  860.             list = (FindBracket(list))->next;
  861.             if (list && list->str[0] == ',')
  862.             argnum++;
  863.         }
  864.         if (list)
  865.             list = list->next;
  866.         }
  867.  
  868.         while (list && list->type == SPACE)
  869.         list = list->next;
  870.  
  871.         if (list) {
  872.         if (list->type == NORMAL && (list->str[0] == ')' || list->str[0] == ',')) {    /* HIER evtl. ein Space erzeugen */
  873.             return (NULL);
  874.         }
  875.         start = list;
  876.         } else {
  877.         if (error)
  878.             *error = ARG_EXPECTED;
  879.         return (NULL);
  880.         }
  881.  
  882.         if (DEBUG & 32)
  883.         printf("- Okay, Arg-Start found: %s\n", start->str);
  884.  
  885.         while (list && (argnum == n)) {
  886.         if (list->type == NORMAL) {
  887.             switch (list->str[0]) {
  888.             case ')':
  889.             case ',':
  890.             argnum++;
  891.             list = list->prev;
  892.             break;
  893.             case '(':
  894.             list = FindBracket(list);
  895.             default:
  896.             if (list)
  897.                 list = list->next;
  898.             break;
  899.             }
  900.         } else if (list)
  901.             list = list->next;
  902.         }
  903.  
  904.         while (list && list->type == SPACE)
  905.         list = list->prev;
  906.  
  907.         if (DEBUG & 32)
  908.         printf("- Okay, Arg-End found: %s\n", list->str);
  909.         return (CloneStrList(start, list));
  910.  
  911.     } else {
  912.         if (error)
  913.         *error = ARG_EXPECTED;
  914.         return (NULL);
  915.     }
  916.     } else
  917.     return (NULL);
  918. }
  919.  
  920. /* ExpandArgMakro - ersetzt ein Makro mit Argumenten */
  921. int ExpandArgMakro(struct mnode *makro, struct strnode **list,
  922.            struct strnode **pos)
  923. {
  924.     struct strnode *clone, *temp, *temp1, *arg, *new;
  925.     struct strnode *prev, *next;
  926.     struct mnode *prevmakro;
  927.     char *newstr;
  928.     int spec, len, x;
  929.  
  930.     clone = CloneStrList(makro->tokenlist, NULL);
  931.     if (!clone)
  932.     return (OUT_OF_MEM);
  933.  
  934.     if (DEBUG & 32)
  935.     printf("ExpandArgMakro - Clone build.\n");
  936.  
  937.     temp = clone;
  938.     while (temp) {
  939.     if (temp->type == ARGUMENT) {
  940.         arg = CloneArg(*pos, temp->number, &x);
  941.         if (!arg) {
  942.         DelStrList(&clone);
  943.         return (x);
  944.         }
  945.         if (DEBUG & 32) {
  946.         printf("ARGUMENT:\n");
  947.         PrintTL(arg);
  948.         printf("Argument found - ");
  949.         }
  950.         if (spec = NextToSpecial(temp)) {
  951.         /* nicht expandieren, nur einsetzen */
  952.         if (spec == TOSTRING) {
  953.  
  954.             if (DEBUG & 32)
  955.             printf("next to #\n");
  956.             /* als String einsetzen */
  957.             new = (struct strnode *) malloc(sizeof(struct strnode));
  958.             if (!new) {
  959.             DelStrList(&clone);
  960.             DelStrList(&arg);
  961.             return (OUT_OF_MEM);
  962.             }
  963.             len = ListStrLen(arg);
  964.             newstr = (char *) malloc(len + 1);
  965.             if (!newstr) {
  966.             DelStrList(&clone);
  967.             DelStrList(&arg);
  968.             if (new)
  969.                 free(new);
  970.             return (OUT_OF_MEM);
  971.             }
  972.             CopyList2StrStr(arg, newstr);
  973.             DelStrList(&arg);
  974.             new->len = len + 2;
  975.             new->flags = new->number = 0;
  976.             new->type = PP_STR;
  977.             new->str = newstr;
  978.  
  979.             prev = temp->prev;
  980.             next = temp->next;
  981.             DelStrNode(NULL, temp);    /* Argument */
  982.  
  983.             while (prev && prev->type == SPACE) {
  984.             temp = prev->prev;
  985.             DelStrNode(&clone, prev);
  986.             prev = temp;
  987.             }
  988.  
  989.             if (prev && prev->type == SPECIAL && prev->flags == TOSTRING) {
  990.             temp = prev->prev;
  991.             DelStrNode(&clone, prev);
  992.             prev = temp;
  993.             } else
  994.             ierror(0);
  995.  
  996.             new->prev = prev;
  997.             if (prev)
  998.             prev->next = new;
  999.             else
  1000.             clone = new;
  1001.             new->next = next;
  1002.             if (next)
  1003.             next->prev = new;
  1004.             temp = new;
  1005.         } else {
  1006.             /* Einfach nur einsetzen */
  1007.             if (DEBUG & 32)
  1008.             printf("next to ##\n");
  1009.             prev = temp->prev;
  1010.             next = temp->next;
  1011.             DelStrNode(NULL, temp);
  1012.             arg->prev = prev;
  1013.             if (prev)
  1014.             prev->next = arg;
  1015.             else
  1016.             clone = arg;
  1017.             while (arg->next)
  1018.             arg = arg->next;
  1019.             arg->next = next;
  1020.             if (next)
  1021.             next->prev = arg;
  1022.             temp = arg;
  1023.         }
  1024.         } else {
  1025.         /* expandieren und einsetzen */
  1026.         if (DEBUG & 32)
  1027.             printf("normal arg\n");
  1028.         if (x = ExpandList(&arg)) {
  1029.             DelStrList(&clone);
  1030.             DelStrList(&arg);
  1031.             return (x);
  1032.         }
  1033.         if (DEBUG & 32) {
  1034.             printf("expanded arg:\n");
  1035.             PrintTL(arg);
  1036.         }
  1037.         prev = temp->prev;
  1038.         next = temp->next;
  1039.         DelStrNode(NULL, temp);
  1040.         arg->prev = prev;
  1041.         if (prev)
  1042.             prev->next = arg;
  1043.         else
  1044.             clone = arg;
  1045.         while (arg->next)
  1046.             arg = arg->next;
  1047.         arg->next = next;
  1048.         if (next)
  1049.             next->prev = arg;
  1050.         temp = arg;
  1051.         }            /* of N2Special */
  1052.     }
  1053.     if (temp)
  1054.         temp = temp->next;
  1055.     }
  1056.  
  1057.     if (DEBUG & 32)
  1058.     printf("Arguments expanded.\n");
  1059.  
  1060.     temp = clone;
  1061.     while (temp) {
  1062.     if (temp->type == SPECIAL && temp->flags == KILLSPACES) {
  1063.         prev = temp->prev;
  1064.         next = temp->next;
  1065.         if ((prev->type == PP_IDENT || prev->type == NUMBER)) {
  1066.         switch (next->type) {
  1067.         case NUMBER:    /* merge -> ident */
  1068.         case PP_IDENT:
  1069.             RemStrNode(&clone, next);
  1070.             MergeStrNodes(prev, next);
  1071.             next = temp->next;
  1072.             /* next will now be deleted and prev->str will be */
  1073.             /* the joined strings from prev&next */
  1074.         default:    /* no merge / del ## */
  1075.             DelStrNode(&clone, temp);
  1076.             temp = next;
  1077.             break;
  1078.         }        /* of switch */
  1079.         } else {
  1080.         DelStrNode(&clone, temp);
  1081.         temp = next;
  1082.         }
  1083.     }
  1084.     if (temp)
  1085.         temp = temp->next;
  1086.     }
  1087.  
  1088.     /* 'makro' aus mlist ausklinken */
  1089.     prevmakro = makro->prev;
  1090.     RemMakroNode(&mlist, makro);
  1091.  
  1092.     /* alles expandieren */
  1093.     if (!(x = ExpandList(&clone))) {
  1094.     /* akt. StrNode durch clone-Liste ersetzen */
  1095.  
  1096.     if (DEBUG & 32) {
  1097.         printf("Complete Makro expanded\n");
  1098.         PrintTL(clone);
  1099.     }
  1100.     /* clone anstelle von pos in list einsetzen */
  1101.     prev = (*pos)->prev;
  1102.     next = (*pos)->next;
  1103.  
  1104.     DelStrNode(NULL, *pos);
  1105.  
  1106. #ifdef bla
  1107.     while (next && next->type == SPACE) {
  1108.         temp = next->next;
  1109.         DelStrNode(NULL, next);    /* SPACE zwischen Makro und Args loeschen */
  1110.         next = temp;
  1111.     }
  1112. #endif
  1113.     while (next && next->type == SPACE)
  1114.         next = next->next;
  1115.     /* SPACE hinter Makro ueberspringen */
  1116.  
  1117.     if (next && next->type == NORMAL && next->str[0] == '(') {
  1118.         temp = next;
  1119.         next = FindBracket(temp);
  1120.         if (next)
  1121.         next = next->next;
  1122.         do {
  1123.         temp1 = temp->next;
  1124.         DelStrNode(NULL, temp);        /* ARG-List hinter Makro loeschen */
  1125.         temp = temp1;
  1126.         } while (temp != next);
  1127.     } else {
  1128.         ierror(0);
  1129.     }
  1130.  
  1131.  
  1132.     /* vor clone ein SPACE einsetzen, wenn nicht PREV==SPACE */
  1133. /*vb:   hier !prev|| wegen Enforcerhit eingesetzt; waere prev&& besser? */
  1134.     if (!prev || prev->type != SPACE) {
  1135.         if (temp = AllocSpace()) {
  1136.         temp->next = clone;
  1137.         if (clone)
  1138.             clone->prev = temp;
  1139.         clone = temp;
  1140.         }
  1141.     }
  1142.     clone->prev = prev;
  1143.     if (prev)
  1144.         prev->next = clone;
  1145.     else
  1146.         *list = clone;
  1147.  
  1148.     while (clone->next)
  1149.         clone = clone->next;
  1150.     /* nach clone ein SPACE einsetzen, wenn nicht NEXT==SPACE */
  1151. /*vb:   hier !next|| wegen Enforcerhit eingesetzt; waere next&& besser? */
  1152.     if (!next || next->type != SPACE) {
  1153.         if (temp = AllocSpace()) {
  1154.         temp->prev = clone;
  1155.         if (clone)
  1156.             clone->next = temp;
  1157.         clone = temp;
  1158.         }
  1159.     }
  1160.     *pos = clone;
  1161.     clone->next = next;
  1162.     if (next)
  1163.         next->prev = clone;
  1164.  
  1165.     /* 'makro' wieder einsetzen */
  1166.     InsertMakroNode(&mlist, makro, prevmakro);
  1167.     return (OK);
  1168.     } else {
  1169.     InsertMakroNode(&mlist, makro, prevmakro);
  1170.     return (x);
  1171.     }
  1172.  
  1173. }
  1174.  
  1175. /* ExpandList - ersetzt alle Makros in der Liste */
  1176. int ExpandList(struct strnode **list)
  1177. {
  1178.     struct mnode *found, *before;
  1179.     struct strnode *clone, *beforestr, *afterstr, *listtemp, *temp2,
  1180.     *temp3;
  1181.     int result = OK;
  1182.  
  1183.     if (DEBUG & 32)
  1184.     puts("ExpandList");
  1185.  
  1186.  
  1187.     listtemp = *list;
  1188.     while (listtemp) {
  1189.  
  1190.     if (listtemp->type == PP_IDENT) {
  1191.  
  1192.         found = FindMakroNode(mlist, listtemp->str, 0);
  1193.         if (found) {
  1194. /*vb: merken, ob mind. ein Makro expandiert wurde   */
  1195.         did_expand = 1;
  1196.         if (found->flags & PARAMETER) {
  1197.             /* Makro mit Argument(en) */
  1198.             if (DEBUG & 32)
  1199.             printf("Makro with args\n");
  1200.  
  1201.             temp2 = listtemp->next;
  1202.             while (temp2 && temp2->type == SPACE)
  1203.             temp2 = temp2->next;
  1204.  
  1205.             if (temp2 && temp2->type == NORMAL && temp2->str[0] == '(')
  1206.             if (result = ExpandArgMakro(found, list, &listtemp))
  1207.                 return (result);
  1208.  
  1209.         } else {
  1210.  
  1211.             /* Makro ohne Argument */
  1212.  
  1213.             /* ExpandNormMakro - expandiert ein Makro ohne Argumente */
  1214.             /* Parameter: s.o. */
  1215.  
  1216.             if (found->flags & FUNCTION) {
  1217.             clone = DoMakroFunction(found);
  1218.             } else {
  1219.             clone = CloneStrList(found->tokenlist, NULL);
  1220.             }
  1221.             if (!clone)
  1222.             return (OUT_OF_MEM);
  1223.             /* akt. MakroNode ausklinken um rekursive Exp. zu verhindern */
  1224.             before = found->prev;
  1225.             RemMakroNode(&mlist, found);
  1226.             if (!(result = ExpandList(&clone))) {
  1227.             /* akt. StrNode durch clone-Liste ersetzen */
  1228.             beforestr = listtemp->prev;
  1229.             afterstr = listtemp->next;
  1230.             DelStrNode(NULL, listtemp);
  1231.             listtemp = afterstr;
  1232.             clone->prev = beforestr;
  1233.             if (beforestr)
  1234.                 beforestr->next = clone;
  1235.             else
  1236.                 *list = clone;
  1237.             while (clone->next)
  1238.                 clone = clone->next;
  1239.             clone->next = afterstr;
  1240.             if (afterstr)
  1241.                 afterstr->prev = clone;
  1242.             /* akt. Makronode wieder einsetzen */
  1243.             InsertMakroNode(&mlist, found, before);
  1244.             } else {
  1245.             /* akt. Makronode wieder einsetzen */
  1246.             InsertMakroNode(&mlist, found, before);
  1247.             return (result);
  1248.             }
  1249.         }
  1250.         }
  1251.     }
  1252.     if (listtemp)
  1253.         listtemp = listtemp->next;
  1254.     }
  1255.  
  1256.     return (OK);
  1257. }
  1258.  
  1259.  
  1260. /* ParseIdentifier - parsed den Input-Define-String und haengt das Makro */
  1261. /*                   in die Liste */
  1262.  
  1263. struct mnode *ParseIdentifier(char *str)
  1264. {
  1265.     int x, numargs = 0, flags = 0, len = 0;
  1266.     char *name = NULL, *args = NULL, *token = NULL, *temp, *temp2, *argtemp;
  1267.     struct mnode *newmakro, *found;
  1268.     struct strnode *tokenlist = NULL, *templist, *arglist = NULL, *templist2;
  1269.     struct strnode *next, *prev;
  1270.  
  1271.     if (DEBUG & 32)
  1272.     puts("ParseIdentifier");
  1273.  
  1274. /*vb: casts eingefuegt  */
  1275.     while (isspace((unsigned char) *str)) {
  1276.     str++;
  1277.     }
  1278.     if (!(isalpha((unsigned char) *str) || *str == '_')) {
  1279.     error(178);
  1280.     return (0);
  1281.     }
  1282.     temp = str;
  1283.     while (isalnum((unsigned char) *temp) || (*temp == '_')) {
  1284.     temp++;
  1285.     len++;
  1286.     }
  1287.  
  1288.     /* auf schon vorhandene (evtl. FESTE) Definition suchen */
  1289.     found = FindMakroNode(mlist, str, len);
  1290.     if (found && (found->flags & NOREDEF)) {
  1291.     error(179);
  1292.     return (0);
  1293.     }
  1294. /*vb:   */
  1295.     if (1) {
  1296.     /* Okay, ist egal, wie das alte Makro aussah */
  1297.  
  1298. /*vb:   */
  1299.     if (found && !(c_flags[15] & USEDFLAG)) {
  1300.         error(197);
  1301.     }
  1302.     temp = name = (char *) malloc(len + 1);        /* Speicher fuer Name-String belegen */
  1303.     if (!name) {
  1304.         error(196);
  1305.         return (0);
  1306.     }
  1307.     for (x = 0; x < len; x++) {
  1308.         *temp++ = *str++;
  1309.     }            /* Namen kopieren */
  1310.     *temp = 0;
  1311.  
  1312.     if (*str == '(') {
  1313.         flags |= PARAMETER;
  1314.         str++;        /* jump over '(' */
  1315.         temp = str;
  1316.         len = 0;
  1317. /*vb: casts eingefuegt  */
  1318.         while (*temp && (*temp != ')'))
  1319.         if (!(isspace((unsigned char) *temp))) {
  1320.             len++;
  1321.             temp++;
  1322.         } else {
  1323.             temp++;
  1324.         }
  1325.         if (*temp == 0) {
  1326.         error(180);
  1327.         if (name)
  1328.             free(name);
  1329.         return (0);
  1330.         }
  1331.         args = temp = (char *) malloc(len + 1);
  1332.         if (!args) {
  1333.         error(196);
  1334.         if (name)
  1335.             free(name);
  1336.         return (0);
  1337.         }
  1338.         for (x = 0; x < len;)
  1339.         if (!(isspace((unsigned char) *str))) {
  1340.             x++;
  1341.             *temp++ = *str++;
  1342.         } else {
  1343.             str++;
  1344.         }
  1345.         *temp = 0;
  1346.         str++;        /* jump over ')' */
  1347.  
  1348.         /* Argumentliste parsen und auf Fehler pruefen */
  1349.         temp = args;
  1350.         while (*temp && (isalpha((unsigned char) *temp) || *temp == '_')) {
  1351.         temp++;
  1352.         while (*temp && (isalnum((unsigned char) *temp) || *temp == '_')) {
  1353.             temp++;
  1354.         }
  1355.         if (!(*temp) || *temp == ',') {
  1356.             numargs++;
  1357.             if ((*temp == ',') && (isalpha((unsigned char) *(temp + 1)) || *(temp + 1) == '_'))
  1358.             temp++;
  1359.         }
  1360.         }
  1361.         if (*temp) {
  1362.         if (args)
  1363.             free(args);
  1364.         if (name)
  1365.             free(name);
  1366.         if (*temp == ',') {
  1367.             error(181);
  1368.         } else {
  1369.             error(182);
  1370.         }
  1371.         return (0);
  1372.         }
  1373.     }
  1374.     while (isspace((unsigned char) *str))
  1375.         str++;        /* Skip Spaces */
  1376.     /* HIER: pruefen, ob tokenlist erstellt werden konnte (leere tokenlist->ok) */
  1377.     tokenlist = Str2List(str);
  1378.     if (DEBUG & 32)
  1379.         printf(" - build TokenList\n");
  1380.     templist = tokenlist;
  1381.     while (templist) {
  1382.         if ((templist->type == NORMAL) && (!strcmp(templist->str, "#"))) {
  1383.  
  1384.         if ((templist->next) && (templist->next->type == NORMAL)
  1385.             && (!strcmp(templist->next->str, "#"))) {
  1386.             /* ## KILLSPACES */
  1387.             if ((templist->prev) && (templist->next->next)) {
  1388.             templist->type = SPECIAL;
  1389.             templist->flags = KILLSPACES;
  1390.             DelStrNode(&tokenlist, templist->next);
  1391.             } else {
  1392.             error(183);
  1393.             if (name)
  1394.                 free(name);
  1395.             if (args)
  1396.                 free(args);
  1397.             if (tokenlist)
  1398.                 DelStrList(&tokenlist);
  1399.             return (0);
  1400.             }
  1401.         }
  1402.         }
  1403.         templist = templist->next;
  1404.     }
  1405.  
  1406.     /* Token parsen/kopieren */
  1407.     if ((flags & PARAMETER)) {    /* Argumente parsen */
  1408.         arglist = NULL;
  1409.         temp = temp2 = args;
  1410.         while (*temp) {
  1411.         len = 0;
  1412.         while (*temp && *temp != ',') {
  1413.             temp++;
  1414.             len++;
  1415.         }
  1416.         if (*temp == ',')
  1417.             temp++;
  1418.         argtemp = (char *) malloc(len + 1);
  1419.         if (!argtemp) {
  1420.             error(196);
  1421.             if (name)
  1422.             free(name);
  1423.             if (args)
  1424.             free(args);
  1425.             if (arglist)
  1426.             DelStrList(&arglist);
  1427.             if (tokenlist)
  1428.             DelStrList(&tokenlist);
  1429.             return (0);
  1430.         }
  1431.         strncpy(argtemp, temp2, len);
  1432.         temp2 = temp;
  1433.         *(argtemp + len) = 0;
  1434.         AddStrNodeBehind(&arglist, NULL, argtemp);
  1435.         }
  1436.         templist = tokenlist;
  1437.         while (templist) {
  1438.         if (templist->type == PP_IDENT) {
  1439.             x = 0;
  1440.             templist2 = arglist;
  1441.             while (templist2) {
  1442.             if (!strcmp(templist->str, templist2->str)) {
  1443.                 templist->type = ARGUMENT;
  1444.                 templist->number = x;
  1445.             }
  1446.             x++;
  1447.             templist2 = templist2->next;
  1448.             }
  1449.         }
  1450.         templist = templist->next;
  1451.         }
  1452.         DelStrList(&arglist);
  1453.         if (DEBUG & 32)
  1454.         printf(" - Arguments found.\n");
  1455.         /* #-Specials korrigieren, nachdem die Argumente erkannt wurden */
  1456.         templist = tokenlist;
  1457.         while (templist) {
  1458.         if ((templist->type == NORMAL) && (!strcmp(templist->str, "#"))) {
  1459.             if ((templist->next) && (templist->next->type == ARGUMENT)) {
  1460.             templist->type = SPECIAL;
  1461.             templist->flags = TOSTRING;
  1462.             } else {
  1463.             error(184);
  1464.             if (name)
  1465.                 free(name);
  1466.             if (args)
  1467.                 free(args);
  1468.             if (arglist)
  1469.                 DelStrList(&arglist);
  1470.             if (tokenlist)
  1471.                 DelStrList(&tokenlist);
  1472.             return (0);
  1473.             }
  1474.         }
  1475.         templist = templist->next;
  1476.         }
  1477.         if (DEBUG & 32)
  1478.         printf(" - Special-# corrected.\n");
  1479.     } else {        /* Token kopieren */
  1480.         temp = str;
  1481.         len = 0;
  1482.         while ((*temp) && (*temp != '\n')) {
  1483.         temp++;
  1484.         len++;
  1485.         }
  1486.         temp = token = (char *) malloc(len + 1);
  1487.         if (!token) {
  1488.         error(196);
  1489.         if (name)
  1490.             free(name);
  1491.         if (args)
  1492.             free(args);
  1493.         if (tokenlist)
  1494.             DelStrList(&tokenlist);
  1495.         return (0);
  1496.         }
  1497.         for (x = 0; x < len; x++) {
  1498.         *temp++ = *str++;
  1499.         }
  1500.         *temp = 0;
  1501.     }
  1502.  
  1503.  
  1504.     templist = tokenlist;
  1505.     while (templist) {
  1506.         if (templist->type == SPECIAL && templist->flags == KILLSPACES) {
  1507.         next = templist->next;
  1508.         prev = templist->prev;
  1509.  
  1510.         /* Kill Spaces before/after ## */
  1511.         while (prev && prev->type == SPACE) {
  1512.             templist2 = prev->prev;
  1513.             DelStrNode(&tokenlist, prev);
  1514.             prev = templist2;
  1515.         }
  1516.         while (next && next->type == SPACE) {
  1517.             templist2 = next->next;
  1518.             DelStrNode(&tokenlist, next);
  1519.             next = templist2;
  1520.         }
  1521.         if ((!next) || (!prev))
  1522.             ierror(0);
  1523.  
  1524.         if (next->type != ARGUMENT && prev->type != ARGUMENT) {
  1525.             if ((prev->type == PP_IDENT || prev->type == NUMBER)) {
  1526.             switch (next->type) {
  1527.             case NUMBER:    /* merge -> ident */
  1528.             case PP_IDENT:
  1529.                 RemStrNode(&tokenlist, next);
  1530.                 MergeStrNodes(prev, next);
  1531.                 next = templist->next;
  1532.                 /* next will now be deleted and prev->str will be */
  1533.                 /* the joined strings from prev&next */
  1534.             default:    /* no merge / del ## */
  1535.                 DelStrNode(&tokenlist, templist);
  1536.                 templist = next;
  1537.                 break;
  1538.             }    /* of switch */
  1539.             } else {
  1540.             DelStrNode(&tokenlist, templist);
  1541.             templist = next;
  1542.             }
  1543.         }
  1544.         }
  1545.         if (templist)
  1546.         templist = templist->next;
  1547.     }
  1548.  
  1549.  
  1550. /* erst HIER bei allowredefinition=0 abfragen ?? */
  1551.  
  1552.     if (newmakro = (struct mnode *) malloc(sizeof(struct mnode))) {
  1553.         newmakro->name = name;
  1554.         newmakro->args = args;
  1555.         newmakro->token = token;
  1556.         newmakro->tokenlist = tokenlist;
  1557.         newmakro->flags = flags;
  1558.         newmakro->funcnum = 0;
  1559.         AddMakroNode(&mlist, newmakro);
  1560.     } else {
  1561.         error(196);
  1562.         if (name)
  1563.         free(name);
  1564.         if (token)
  1565.         free(token);
  1566.         if (args)
  1567.         free(args);
  1568.         if (tokenlist)
  1569.         DelStrList(&tokenlist);
  1570.     }
  1571.     return (newmakro);
  1572.  
  1573.     } else {
  1574. /*vb:   das ist irgendwie Unsinn hier, glaube ich   */
  1575.     ierror(0);
  1576.     /* HIER: ueberpruefen, ob Macrodefinitionen uebereinstimmen, sonst Error */
  1577.     if (*temp == '(') {
  1578.         if (found->flags & PARAMETER) {
  1579.         temp++;        /* skip ( */
  1580.  
  1581.  
  1582.  
  1583.         } else {
  1584.         error(185);
  1585.         return (NULL);
  1586.         }
  1587.     }
  1588.     /* HIER nur noch tokenlisten vergleichen */
  1589.  
  1590.     }
  1591.     if (DEBUG & 32)
  1592.     printf("ParseIdent falls of\n");
  1593. }
  1594.  
  1595.  
  1596. /* PreParse - 3-Zeichen-Folgen ersetzen, \+CR Zeilen anhaengen, usw.. */
  1597.  
  1598. int PreParse()
  1599. {
  1600.     char *src, *dest, *dest2;
  1601.     int slen, dlen = 0;
  1602.     int cat = 0;        /*vb: um zu merken, ob Zeilen mit \ verbunden werden */
  1603.     dest2 = string;
  1604.  
  1605.     if (DEBUG & 32)
  1606.     puts("PreParse");
  1607.  
  1608.  
  1609.     if (!fgets(ppstring, MAXPPINPUT, in[incnesting])) {
  1610.     if (cmtnesting)
  1611.         error(186);
  1612. /*vb:   */
  1613. /*      if(ifstatus[incnesting]) error(186); */
  1614. /*      ifnesting--; */
  1615.     if (DEBUG & 32)
  1616.         printf("-- end of file  ifnesting-1:%d\n\n", incnesting);
  1617.     if (incnesting) {
  1618.         fclose(in[incnesting]);
  1619.         incnesting--;
  1620.         return (pp_nextline());
  1621.     } else
  1622.         return (0);
  1623.     } else if (DEBUG & 32)
  1624.     printf("gets1:%s\n", ppstring);        /*vb: */
  1625.  
  1626.     if ((strlen(ppstring) == (MAXPPINPUT - 1)) && (ppstring[MAXPPINPUT - 2] != '\n')) {
  1627.     error(177);
  1628.     return (0);
  1629.     }
  1630.     zn[incnesting]++;
  1631.     linenr = zn[incnesting];
  1632.  
  1633.     do {
  1634.     /* Zeilen einlesen, bis kein Kommentar mehr */
  1635.  
  1636.     /* Zeilen einlesen bis kein \ mehr am Ende */
  1637.     do {
  1638.         /* Source-String an Dest-String anhaengen und ??x-Folgen ersetzen */
  1639. /*vb: das killt sonst das angehaengte wieder   */
  1640.         if (cat == 0) {
  1641.         dest = src = ppstring;
  1642.         slen = 0;
  1643.         }
  1644.         do {
  1645.         if (*src != '\n') {
  1646.  
  1647.             if ((*src == '?') && (*(src + 1) == '?') && !(c_flags[16] & USEDFLAG)) {
  1648.             switch (*(src + 2)) {
  1649.             case '=':
  1650.                 *dest++ = '#';
  1651.                 src += 2;
  1652.                 break;
  1653.             case '/':
  1654.                 *dest++ = '\\';
  1655.                 src += 2;
  1656.                 break;
  1657.             case '\'':
  1658.                 *dest++ = '^';
  1659.                 src += 2;
  1660.                 break;
  1661.             case '(':
  1662.                 *dest++ = '[';
  1663.                 src += 2;
  1664.                 break;
  1665.             case ')':
  1666.                 *dest++ = ']';
  1667.                 src += 2;
  1668.                 break;
  1669.             case '!':
  1670.                 *dest++ = '|';
  1671.                 src += 2;
  1672.                 break;
  1673.             case '<':
  1674.                 *dest++ = '{';
  1675.                 src += 2;
  1676.                 break;
  1677.             case '>':
  1678.                 *dest++ = '}';
  1679.                 src += 2;
  1680.                 break;
  1681.             case '-':
  1682.                 *dest++ = '~';
  1683.                 src += 2;
  1684.                 break;
  1685.             default:
  1686.                 *dest++ = *src;
  1687.                 break;
  1688.             }    /* of switch */
  1689.             } else {
  1690.             *dest++ = *src;
  1691.             }
  1692.  
  1693.             if (slen < MAXPPINPUT) {
  1694.             slen++;
  1695.             } else {
  1696.             error(177);
  1697.             return (0);
  1698.             }
  1699.         }
  1700.         } while (*src++);
  1701.  
  1702.         src = dest;
  1703.         /* dest->lastchar+2/NULL+1 (dest-1)-> 0 (dest-2)->lastchar */
  1704.         if (*(dest - 2) == '\\') {
  1705.         /*vb: sollte das slen statt dlen sein?  */
  1706.         if (fgets(src, MAXPPINPUT - dlen, in[incnesting])) {
  1707.             if (DEBUG & 32)
  1708.             printf("gets2:%s\n", src);    /*vb:  */
  1709. /* Hier auf LF+0 abfragen */
  1710.             dest -= 2;
  1711.             zn[incnesting]++;
  1712.             cat = 1;    /*vb: merken, dass Zeilen verbunden wurden */
  1713.         }
  1714.         }
  1715.     } while (*dest == '\\');
  1716.  
  1717.     src = ppstring;
  1718.     while (*src) {
  1719.         /* ' Strings ueberlesen */
  1720.         if ((*src == '\'') && (!cmtnesting)) {
  1721.         if (dlen < MAXINPUT) {
  1722.             *dest2++ = *src++;
  1723.             dlen++;
  1724.         } else {
  1725.             error(177);
  1726.             return (0);
  1727.         }
  1728.         while (*src && *src != '\'') {
  1729.             if (*src == '\\') {
  1730.             *dest2++ = *src++;
  1731.             dlen++;
  1732.             };
  1733.             if (dlen < MAXINPUT) {
  1734.             *dest2++ = *src++;
  1735.             dlen++;
  1736.             } else {
  1737.             error(177);
  1738.             return (0);
  1739.             }
  1740.         }
  1741.         if (dlen < MAXINPUT) {
  1742.             *dest2++ = *src++;
  1743.             dlen++;
  1744.         } else {
  1745.             error(177);
  1746.             return (0);
  1747.         }
  1748.         }
  1749.         /* " Strings ueberlesen */
  1750.         if ((*src == '\"') && (!cmtnesting)) {
  1751.         *dest2++ = *src++;
  1752.         dlen++;
  1753.         while (*src && *src != '\"') {
  1754.             if (*src == '\\') {
  1755.             *dest2++ = *src++;
  1756.             dlen++;
  1757.             };
  1758.             if (dlen < MAXINPUT) {
  1759.             *dest2++ = *src++;
  1760.             dlen++;
  1761.             } else {
  1762.             error(177);
  1763.             return (0);
  1764.             }
  1765.         }
  1766.         if (dlen < MAXINPUT) {
  1767.             *dest2++ = *src++;
  1768.             dlen++;
  1769.         } else {
  1770.             error(177);
  1771.             return (0);
  1772.         }
  1773.         }
  1774.         /* Kommentare weglassen */
  1775.         if ((*src == '/') && (*(src + 1) == '*')) {
  1776.         src += 2;
  1777.         if (dlen < MAXINPUT) {
  1778.             *dest2++ = ' ';
  1779.             dlen++;
  1780.         } else {
  1781.             error(177);
  1782.             return (0);
  1783.         }
  1784.         if ((cmtnesting && (c_flags[13] & USEDFLAG)) || (!cmtnesting))
  1785.             cmtnesting++;
  1786.         else
  1787.             error(198);
  1788.         } else {
  1789.         if ((*src == '*') && (*(src + 1) == '/') && cmtnesting) {
  1790.             src += 2;
  1791.             cmtnesting--;
  1792.         }
  1793.         }
  1794.  
  1795.         /* C++-Comment weglassen */
  1796.         if ((!cmtnesting) && (*src == '/') && (*(src + 1) == '/') && (c_flags[14] & USEDFLAG))
  1797.         *src = 0;
  1798.  
  1799.         if (!cmtnesting) {
  1800.         if (*src) {
  1801.             *dest2++ = *src++;
  1802.         }
  1803.         if (dlen < MAXINPUT) {
  1804.             dlen++;
  1805.         } else {
  1806.             error(177);
  1807.             return (0);
  1808.         }
  1809.         } else {
  1810.         if (*src)
  1811.             src++;
  1812.         }
  1813.     }
  1814.  
  1815.     if (cmtnesting) {
  1816.         if (!fgets(ppstring, MAXPPINPUT, in[incnesting])) {
  1817.         if (cmtnesting)
  1818.             error(186);
  1819.         if (incnesting) {
  1820.             fclose(in[incnesting]);
  1821.             incnesting--;
  1822.             return (pp_nextline());
  1823.         } else
  1824.             return (0);
  1825.         } else if (DEBUG & 32)
  1826.         printf("gets2:%s\n", ppstring);        /*vb:   */
  1827.  
  1828.         if ((strlen(ppstring) == (MAXPPINPUT - 1)) && (ppstring[MAXPPINPUT - 2] != '\n')) {
  1829.         error(177);
  1830.         return (0);
  1831.         }
  1832.         zn[incnesting]++;
  1833.     }
  1834.     } while (cmtnesting);
  1835.  
  1836. /*vb: das ueberschreibt den Speicher */
  1837. #if 0
  1838.     *dest2-- = 0;
  1839.     while (isspace(*dest2))
  1840.     *dest2-- = 0;        /* Spaces killen */
  1841. #endif
  1842.  
  1843. /*vb: hoffe, das ist besser */
  1844.     *dest2 = 0;
  1845.     while (dest2 > string && isspace((unsigned char) *--dest2))
  1846.     *dest2 = 0;
  1847.  
  1848.  
  1849.     return (1);
  1850. }
  1851.  
  1852. /* **************** PreProcessor ***************** */
  1853.  
  1854. int pp_init(void)
  1855. {
  1856.     char *macroname;
  1857.     struct mnode *macronode;
  1858.  
  1859.     if (!(c_flags[6] & USEDFLAG))
  1860.     printf("%s\n", pp_version);
  1861.  
  1862.     incnesting = /*ifnesting= */ -1;    /*vb:  */
  1863.     cmtnesting = if_cnt = abs_if_cnt = 0;
  1864.     mlist = NULL;
  1865.     strlist = NULL;
  1866.  
  1867.     macroname = (char *) malloc(9);
  1868.     if (!macroname)
  1869.     return (0);
  1870.     strcpy(macroname, "__LINE__");
  1871.     macronode = (struct mnode *) malloc(sizeof(struct mnode));
  1872.     if (!macronode) {
  1873.     if (macroname)
  1874.         free(macroname);
  1875.     return (0);
  1876.     }
  1877.     macronode->name = macroname;
  1878.     macronode->args = macronode->token = NULL;
  1879.     macronode->tokenlist = NULL;
  1880.     macronode->flags = FUNCTION | NODELETE | NOREDEF;
  1881.     macronode->funcnum = FUNCLINE;
  1882.     AddMakroNode(&mlist, macronode);
  1883.  
  1884.     macroname = (char *) malloc(9);
  1885.     if (!macroname)
  1886.     return (0);
  1887.     strcpy(macroname, "__FILE__");
  1888.     macronode = (struct mnode *) malloc(sizeof(struct mnode));
  1889.     if (!macronode) {
  1890.     if (macroname)
  1891.         free(macroname);
  1892.     DelMakroList(&mlist);
  1893.     return (0);
  1894.     }
  1895.     macronode->name = macroname;
  1896.     macronode->args = macronode->token = NULL;
  1897.     macronode->tokenlist = NULL;
  1898.     macronode->flags = FUNCTION | NODELETE | NOREDEF;
  1899.     macronode->funcnum = FUNCFILE;
  1900.     AddMakroNode(&mlist, macronode);
  1901.  
  1902.     macroname = (char *) malloc(9);
  1903.     if (!macroname)
  1904.     return (0);
  1905.     strcpy(macroname, "__DATE__");
  1906.     macronode = (struct mnode *) malloc(sizeof(struct mnode));
  1907.     if (!macronode) {
  1908.     if (macroname)
  1909.         free(macroname);
  1910.     DelMakroList(&mlist);
  1911.     return (0);
  1912.     }
  1913.     macronode->name = macroname;
  1914.     macronode->args = macronode->token = NULL;
  1915.     macronode->tokenlist = NULL;
  1916.     macronode->flags = FUNCTION | NODELETE | NOREDEF;
  1917.     macronode->funcnum = FUNCDATE;
  1918.     AddMakroNode(&mlist, macronode);
  1919.  
  1920.     macroname = (char *) malloc(9);
  1921.     if (!macroname)
  1922.     return (0);
  1923.     strcpy(macroname, "__TIME__");
  1924.     macronode = (struct mnode *) malloc(sizeof(struct mnode));
  1925.     if (!macronode) {
  1926.     if (macroname)
  1927.         free(macroname);
  1928.     DelMakroList(&mlist);
  1929.     return (0);
  1930.     }
  1931.     macronode->name = macroname;
  1932.     macronode->args = macronode->token = NULL;
  1933.     macronode->tokenlist = NULL;
  1934.     macronode->flags = FUNCTION | NODELETE | NOREDEF;
  1935.     macronode->funcnum = FUNCTIME;
  1936.     AddMakroNode(&mlist, macronode);
  1937.  
  1938.     macroname = (char *) malloc(9);
  1939.     if (!macroname)
  1940.     return (0);
  1941.     strcpy(macroname, "__STDC__");
  1942.     macronode = (struct mnode *) malloc(sizeof(struct mnode));
  1943.     if (!macronode) {
  1944.     if (macroname)
  1945.         free(macroname);
  1946.     DelMakroList(&mlist);
  1947.     return (0);
  1948.     }
  1949.     macronode->name = macroname;
  1950.     macronode->args = NULL;
  1951.     macroname = (char *) malloc(2);
  1952.     if (!macroname) {
  1953.     if (macronode->name)
  1954.         free(macronode->name);
  1955.     if (macronode)
  1956.         free(macronode);
  1957.     DelMakroList(&mlist);
  1958.     return (0);
  1959.     }
  1960.     strcpy(macroname, "1");
  1961.     macronode->token = macroname;
  1962.     macronode->tokenlist = Str2List(macroname);
  1963.     if (!macronode->tokenlist) {
  1964.     if (macronode->name)
  1965.         free(macronode->name);
  1966.     if (macronode->token)
  1967.         free(macronode->token);
  1968.     if (macronode)
  1969.         free(macronode);
  1970.     DelMakroList(&mlist);
  1971.     return (0);
  1972.     }
  1973.     macronode->flags = NODELETE;
  1974.     macronode->funcnum = 0;
  1975.     AddMakroNode(&mlist, macronode);
  1976.  
  1977.     return (1);
  1978. }
  1979.  
  1980.  
  1981. void pp_free(void)
  1982. {
  1983.     int i;
  1984.  
  1985.     if (DEBUG & 32)
  1986.     puts("pp_free");
  1987.  
  1988. /*vb: Schleifenindex korrekt gesetzt    */
  1989.     for (i = incnesting; i >= 0; i--)
  1990.     if (in[i])
  1991.         fclose(in[i]);
  1992.     DelMakroList(&mlist);
  1993.     DelStrList(&strlist);
  1994. }
  1995.  
  1996. int pp_include(char *f)
  1997. {
  1998.     if (DEBUG & 32)
  1999.     printf("trying to include %s\n", f);    /*vb:  */
  2000.  
  2001.     if (incnesting >= MAXINCNESTING - 1) {
  2002.     error(187);
  2003.     return (0);
  2004.     }
  2005. /*vb:   */
  2006. /*    if(ifnesting>=MAXIFNESTING-1)   {error("Too many nested #ifs or #includes",0);return(0);} */
  2007.     incnesting++;
  2008.     /*    ifnesting++; *//*vb:   */
  2009.     ifstatus[incnesting] = 0;    /*vb:   */
  2010.  
  2011.     if (DEBUG & 32)
  2012.     printf("-- include: ifnesting:%d ifstatus:0 \n\n", incnesting);
  2013.  
  2014.     in[incnesting] = fopen(f, "r");
  2015.     if (!in[incnesting]) {
  2016.     incnesting--;
  2017.     return (0);
  2018.     }
  2019.     filename[incnesting] = f;
  2020.     zn[incnesting] = linenr = 0;
  2021.     return (1);
  2022. }
  2023.  
  2024.  
  2025.  
  2026. /* ********************** Main-Function ******************* */
  2027. int pp_nextline(void)
  2028. {
  2029.     char *src, *dest, *temp;
  2030.     int complete_len, len, i, result;
  2031.     struct mnode *makro;
  2032.     struct strnode *linelist, *inclinelist;
  2033.  
  2034.     if (DEBUG & 32)
  2035.     puts("pp_nextline");
  2036.  
  2037.     dest = string;
  2038.     dest[0] = 0;
  2039.  
  2040.     /* String vorbereiten, 3ZF ersetzen, \-Zeilen anhaengen, Kommentare loeschen */
  2041.     if (!PreParse())
  2042.     return (0);
  2043.  
  2044.     /* Ueberpruefung auf PreProcessor-Commands */
  2045.     src = string;
  2046. /*vb: casts eingefuegt  */
  2047.     while (isspace((unsigned char) *src)) {
  2048.     src++;
  2049.     }                /* SkipSpaces */
  2050.  
  2051.     if (*src == '#') {        /* #-Direktive gefunden */
  2052.     src++;            /* # ueberlesen */
  2053.  
  2054.     while (isspace((unsigned char) *src)) {
  2055.         src++;
  2056.     }            /* SkipSpaces */
  2057.  
  2058. /*vb:   Direktiven, die nichts mit #if etc. zu tun haben, nach hinten   */
  2059.  
  2060.  
  2061. /* IFDEF */
  2062.     if (!strncmp(src, "ifdef", 5)) {
  2063.         src += 5;
  2064.         abs_if_cnt++;    /*vb: */
  2065.         if (isspace((unsigned char) *src)) {
  2066.         while (isspace((unsigned char) *src)) {
  2067.             src++;
  2068.         }
  2069.         /* identifier suchen */
  2070.         if (do_output) {
  2071. /*vb:   */
  2072. /*            if(ifnesting>=MAXIFNESTING-1) {error("Too many nested #if's",0); return(0);} */
  2073. /*            ifnesting++; */
  2074.             temp = src;
  2075.             len = 0;
  2076.             while ((isalnum((unsigned char) *temp)) || (*temp == '_')) {
  2077.             temp++;
  2078.             len++;
  2079.             }
  2080.             makro = FindMakroNode(mlist, src, len);
  2081.             if (DEBUG & 32)
  2082.             printf("-- #ifdef found, ");
  2083.             if (makro) {
  2084. /*vb:   */
  2085.             ifstatus[incnesting] = 1;    /* Bedingung == TRUE */
  2086.             if (DEBUG & 32)
  2087.                 printf(" condition '%s' found     (TRUE)\n", makro->name);
  2088.             } else {
  2089. /*vb:   */
  2090.             ifstatus[incnesting] = 2;    /* Bedingung == FALSE */
  2091.             do_output = 0;
  2092.             if (DEBUG & 32)
  2093.                 printf(" condition not found (FALSE)\n\n");
  2094.             }
  2095.         } else {
  2096.             if_cnt++;
  2097.             if (DEBUG & 32)
  2098.             printf("-- #ifdef found and if_cnt increased\n\n");
  2099.         }
  2100.         string[0] = 0;    /*vb: yo   */
  2101.         return (1);
  2102.         }
  2103.     }            /* EO IFDEF */
  2104.     /* IFNDEF */
  2105.     if (!strncmp(src, "ifndef", 6)) {
  2106.         src += 6;
  2107.         abs_if_cnt++;    /*vb: */
  2108.         if (isspace((unsigned char) *src)) {
  2109.         while (isspace((unsigned char) *src)) {
  2110.             src++;
  2111.         }
  2112.  
  2113.         /* identifier suchen */
  2114.         if (do_output) {
  2115. /*vb:   */
  2116. /*            if(ifnesting>=MAXIFNESTING-1) {error("Too many nested #if's",0); return(0);} */
  2117. /*            ifnesting++; */
  2118.             temp = src;
  2119.             len = 0;
  2120.             while ((isalnum((unsigned char) *temp)) || (*temp == '_')) {
  2121.             temp++;
  2122.             len++;
  2123.             }
  2124.             if (DEBUG & 32)
  2125.             printf("-- FindMakroNode: len=%d temp=%8lx\n", len, temp);
  2126.             makro = FindMakroNode(mlist, src, len);
  2127.             if (DEBUG & 32)
  2128.             printf("-- #ifndef found, ");
  2129.             if (!makro) {
  2130. /*vb:   */
  2131.             ifstatus[incnesting] = 1;    /* Bedingung == TRUE (Makro not existing) */
  2132.             if (DEBUG & 32)
  2133.                 printf(" condition not found  (TRUE)\n\n");
  2134.             } else {
  2135. /*vb:   */
  2136.             ifstatus[incnesting] = 2;    /* Bedingung == FALSE */
  2137.             do_output = 0;
  2138.             if (DEBUG & 32)
  2139.                 printf(" condition '%s'     found (FALSE)\n\n", makro->name);
  2140.             }
  2141.             /* HIER: string[0]=0; */
  2142.         } else {
  2143.             if_cnt++;
  2144.             if (DEBUG & 32)
  2145.             printf("-- #ifndef found and if_cnt increased\n\n");
  2146.         }
  2147.         string[0] = 0;    /*vb:   */
  2148.         return (1);
  2149.         }
  2150.     }            /* EO IFNDEF */
  2151.     /* IF */
  2152.     if (!strncmp(src, "if", 2)) {
  2153.         src += 2;
  2154.         abs_if_cnt++;    /*vb:   */
  2155.         if (isspace((unsigned char) *src)) {
  2156.         while (isspace((unsigned char) *src)) {
  2157.             src++;
  2158.         }
  2159.         /* Bedingung auswerten */
  2160.  
  2161.  
  2162.  
  2163.         printf("****** WARNING ******* #if is not yet implemented\n");
  2164.  
  2165.  
  2166.         string[0] = 0;    /*vb:   */
  2167.         return (1);
  2168.         }
  2169.     }            /* EO IF */
  2170.     /* ELIF */
  2171.     if (!strncmp(src, "elif", 4)) {
  2172.         src += 4;
  2173.         if (isspace((unsigned char) *src)) {
  2174.         while (isspace((unsigned char) *src)) {
  2175.             src++;
  2176.         }
  2177.         /* Bedingung auswerten */
  2178.  
  2179.  
  2180.  
  2181.  
  2182.  
  2183.         printf("****** WARNING ******* #elif is not yet implemented\n");
  2184.  
  2185.  
  2186.  
  2187.  
  2188.         string[0] = 0;    /*vb:   */
  2189.         return (1);
  2190.         }
  2191.     }            /* EO ELIF */
  2192.     /* ELSE */
  2193.     if (!strncmp(src, "else", 4)) {
  2194.         src += 4;
  2195.         if (isspace((unsigned char) *src) || *src == 0) {
  2196.         while (isspace((unsigned char) *src)) {
  2197.             src++;
  2198.         }
  2199.  
  2200.         if (!if_cnt) {
  2201.             switch (ifstatus[incnesting]) {    /*vb:   */
  2202.             case 0:
  2203.             error(188);
  2204.             return (0);
  2205.             break;
  2206.             case 1:
  2207.             do_output = 0;
  2208.             /* HIER: auf #endif suchen SearchENDIF(); */
  2209.             /* HIER: ifnesting--; do_output=1; */
  2210.             break;
  2211.             case 2:
  2212.             ifstatus[incnesting] = 3;    /*vb:   */
  2213.             do_output = 1;
  2214.             break;
  2215.             case 3:
  2216.             error(189);
  2217.             return (0);
  2218.             break;
  2219.             }
  2220.         }
  2221.         string[0] = 0;    /*vb:    */
  2222.         return (1);
  2223.         }
  2224.     }            /* EO ELSE */
  2225.     /* ENDIF */
  2226.     if (!strncmp(src, "endif", 5)) {
  2227.         src += 5;
  2228.         abs_if_cnt--;    /*vb:   */
  2229.         if (isspace((unsigned char) *src) || *src == 0) {
  2230.         while (isspace((unsigned char) *src)) {
  2231.             src++;
  2232.         }
  2233.         /* HIER: Auf Zeilenende testen */
  2234.  
  2235.         if (DEBUG & 32)
  2236.             printf("-- #endif found, ");
  2237.  
  2238.         if (if_cnt) {
  2239.             if_cnt--;
  2240.             if (DEBUG & 32)
  2241.             printf("if_cnt decreased (to %d)\n", if_cnt);
  2242.         } else {
  2243.             if (DEBUG & 32)
  2244.             printf("ifnesting: %d  ifstatus: %d\n", incnesting, ifstatus[incnesting]);
  2245.             if (abs_if_cnt < 0 /*(incnesting==-1)||ifstatus[incnesting]==0 */ ) {    /*vb:   */
  2246.             error(190);
  2247.             return (0);
  2248.             }
  2249.             /*            ifnesting--; *//*vb:   */
  2250.             /* HIER: evtl. do_output entsprechend ifstatus[] setzen */
  2251.             /*vb: natuerlich    */
  2252.             do_output = 1;
  2253.             ifstatus[incnesting] = abs_if_cnt > 0;    /*vb: 1 oder 0   */
  2254.         }
  2255.         string[0] = 0;    /*vb: ja */
  2256.         return (1);
  2257.         }
  2258.     }            /* EO ENDIF */
  2259.     /*vb: andere Direktiven gegebenenfalls ueberspringen    */
  2260.     if (!do_output) {
  2261.         if (DEBUG & 32)
  2262.         printf("do_output==0 => skipping: %s\n", src);
  2263.         string[0] = 0;
  2264.         return (1);
  2265.     }
  2266. /* DEFINE */
  2267.     if ( /*(do_output)&& */ (!strncmp(src, "define", 6))) {        /*vb:   */
  2268.         if (DEBUG & 32)
  2269.         printf("#define found\n");
  2270.         src += 6;
  2271.         if (isspace((unsigned char) *src)) {
  2272.         while (isspace((unsigned char) *src)) {
  2273.             src++;
  2274.         }
  2275.         if (ParseIdentifier(src)) {
  2276.             string[0] = 0;
  2277.             return (1);
  2278.         } else {
  2279.             if (DEBUG & 32)
  2280.             printf("ParseIdent returned 0\n");
  2281.             return (0);
  2282.         }
  2283.         }
  2284.     }            /* EO DEFINE */
  2285.     /* UNDEF */
  2286.     if ( /*(do_output)&& */ (!strncmp(src, "undef", 5))) {    /*vb:   */
  2287.         src += 5;
  2288.         if (isspace((unsigned char) *src)) {
  2289.         while (isspace((unsigned char) *src)) {
  2290.             src++;
  2291.         }
  2292.         temp = src;
  2293.         len = 0;
  2294.         while ((isalnum((unsigned char) *temp)) || (*temp == '_')) {
  2295.             temp++;
  2296.             len++;
  2297.         }
  2298.         makro = FindMakroNode(mlist, src, len);
  2299.         if (makro->flags & NODELETE) {
  2300.             error(199);
  2301.         } else {
  2302.             DelMakroNode(&mlist, makro);
  2303.         }
  2304.         while (isspace((unsigned char) *temp)) {
  2305.             temp++;
  2306.         }
  2307.         if (*temp != 0 && *temp != '\n') {
  2308.             error(200);
  2309.         }
  2310.         string[0] = 0;
  2311.         return (1);
  2312.         }
  2313.     }            /* EO UNDEF */
  2314.     /* INCLUDE */
  2315.     if ( /*(do_output)&& */ (!strncmp(src, "include", 7))) {    /*vb:   */
  2316.         src += 7;
  2317.         if (isspace((unsigned char) *src)) {
  2318.         while (isspace((unsigned char) *src)) {
  2319.             src++;
  2320.         }
  2321.         if (*src != '<' && *src != '\"') {
  2322.             /* Versuchen den Rest zu expandieren */
  2323.             inclinelist = Str2List(src);
  2324.             if (!ExpandList(&inclinelist)) {
  2325.             if (List2Str(inclinelist, src, MAXINPUT - (src - string))) {
  2326.                 /* HIER exit ? */
  2327.             }
  2328.             } else {
  2329.             error(191);    /* HIER exit ? */
  2330.             }
  2331.         }
  2332. /*vb: geaendert, so dass #include "..." auch noch im Standardpfad sucht */
  2333.         if (DEBUG & 32)
  2334.             printf("includename=%s\n", src);
  2335.         if (*src == '<' || *src == '\"') {
  2336.             char *m = src, c;
  2337.             if (*src == '<')
  2338.             c = '>';
  2339.             else
  2340.             c = '\"';
  2341.             if (*src == '\"') {
  2342.             /* im aktuellen Verzeichnis suchen und includen */
  2343.             src++;
  2344.             temp = src;
  2345.             len = 0;
  2346.             while (*temp != '\"') {
  2347.                 temp++;
  2348.                 len++;
  2349.             }
  2350.             temp++;
  2351.             while (isspace((unsigned char) *temp))
  2352.                 temp++;
  2353.             if (*temp) {
  2354.                 error(200);
  2355.             }
  2356.             temp = (char *) malloc(len + 1);
  2357.             if (temp) {
  2358.                 strncpy(temp, src, len);
  2359.                 *(temp + len) = 0;
  2360.                 if (pp_include(temp)) {
  2361.                 AddStrNode(&strlist, NULL, temp);
  2362.                 string[0] = 0;
  2363.                 return (1);
  2364.                 } else {
  2365.                 if (temp)
  2366.                     free(temp);
  2367. /*vb:
  2368.    error("pp: cannot open file to include",0);
  2369.    return(0); */
  2370.                 }
  2371.             } else {
  2372.                 error(196);
  2373.             }    /* HIER: Exit? */
  2374.             }
  2375.             /* in den Standard-Verzeichnissen suchen und includen */
  2376.             src = m;
  2377.             src++;
  2378.             temp = src;
  2379.             len = 0;
  2380.             while (*temp != c && *temp != 0) {
  2381.             temp++;
  2382.             len++;
  2383.             }        /*vb: sicherer */
  2384.             temp++;
  2385.             while (isspace((unsigned char) *temp))
  2386.             temp++;
  2387.             if (*temp) {
  2388.             error(200);
  2389.             }
  2390.             temp = NULL;
  2391.             for (i = 0; i < incpathc; i++) {
  2392.             complete_len = strlen(incpath[i]) + len;
  2393.             temp = (char *) malloc(complete_len + 1);
  2394.             if (temp) {
  2395.                 strcpy(temp, incpath[i]);
  2396.                 strncat(temp, src, len);
  2397.                 *(temp + complete_len) = 0;
  2398.                 if (pp_include(temp)) {
  2399.                 AddStrNode(&strlist, NULL, temp);
  2400.                 if (DEBUG & 32)
  2401.                     printf("include <%s> found\n", temp);
  2402.                 string[0] = 0;
  2403.                 return (1);
  2404.                 } else {
  2405.                 if (temp)
  2406.                     free(temp);
  2407.                 }
  2408.             } else {
  2409.                 error(196);
  2410.             }    /* HIER: Exit ? */
  2411.             }        /* of FOR i */
  2412.             error(191);
  2413.             return (0);
  2414.         } else {
  2415.             error(192);
  2416.             return (0);
  2417.         }
  2418.         } else {
  2419.         error(193);
  2420.         return (0);
  2421.         }
  2422.     }            /* EO INCLUDE */
  2423.     /* LINE */
  2424.     if (!strncmp(src, "line", 4)) {
  2425.         src += 4;
  2426.         if (isspace((unsigned char) *src)) {
  2427.         return (1);    /* Ignorieren und an Compiler weiterreichen */
  2428.         }
  2429.     }            /* EO LINE */
  2430.     /* ERROR */
  2431.     if (!strncmp(src, "error", 5)) {
  2432.         src += 5;
  2433.         if (isspace((unsigned char) *src)) {
  2434.         while (isspace((unsigned char) *src)) {
  2435.             src++;
  2436.         }
  2437.  
  2438.         return (1);
  2439.         }
  2440.     }            /* EO ERROR */
  2441.     /* PRAGMA */
  2442.     if (!strncmp(src, "pragma", 6)) {
  2443.         src += 6;
  2444.         if (isspace((unsigned char) *src)) {
  2445.         while (isspace((unsigned char) *src)) {
  2446.             src++;
  2447.         }
  2448.  
  2449.         return (1);
  2450.         }
  2451.     }            /* EO PRAGMA */
  2452.     /* Unknown */
  2453.     /*    if(do_output){ */
  2454.     /*vb:   */
  2455.     error(193);
  2456.     return (0);
  2457.     /*    } *//*vb:   */
  2458.     } else if (do_output) {
  2459.     /* Normale Anweisung. Komplette Zeile expandieren */
  2460.  
  2461. /*vb:   */
  2462.  
  2463.     linelist = Str2List(string);
  2464.  
  2465.     if (DEBUG & 32)
  2466.         PrintTL(linelist);
  2467.  
  2468. /*vb: */
  2469.     did_expand = 0;
  2470.  
  2471.     if (result = ExpandList(&linelist)) {
  2472.         switch (result) {
  2473.         case OUT_OF_MEM:
  2474.         error(196);
  2475.         break;
  2476.         case NUM_OF_ARGS:
  2477.         error(194);
  2478.         break;
  2479.         case ARG_EXPECTED:
  2480.         error(195);
  2481.         break;
  2482.         default:
  2483.         ierror(0);
  2484.         break;
  2485.         }
  2486.         DelStrList(&linelist);
  2487.         return (0);
  2488.     }
  2489.     if (DEBUG & 32)
  2490.         PrintTL(linelist);
  2491.  
  2492. /*vb: List2Str nur aufrufen, falls etwas expandiert wurde   */
  2493.     if (did_expand && !List2Str(linelist, string, MAXINPUT)) {
  2494.         DelStrList(&linelist);
  2495.         return (0);
  2496.     }
  2497.     DelStrList(&linelist);
  2498.  
  2499. /*vb:   */
  2500.     } else
  2501.     string[0] = 0;
  2502.     return (1);
  2503. }
  2504.